package com.example.ailiyuncloud.service.Impl;

import com.example.ailiyuncloud.beCurrent.ExecutorConfig;
import com.example.ailiyuncloud.beCurrent.SqlContext;
import com.example.ailiyuncloud.dto.ThreadServiceDto;
import com.example.ailiyuncloud.mapper.ThreadServiceMapper;
import com.example.ailiyuncloud.service.ThreadService;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import static com.example.ailiyuncloud.beCurrent.ExecutorConfig.averageAssign;

/**
 * @Author: lqj
 * @Date: 2024/03/27/21:32
 * @Description:
 */
@Service
public class ThreadServiceImpl implements ThreadService {

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    private ThreadServiceMapper threadServiceMapper;

    @Autowired
    private PlatformTransactionManager transactionManager;


    @Override
    public void synchronousService(List<ThreadServiceDto> list) throws Exception {

        boolean isRunning = true;
        //根据sqlSessionTemplate获取SqlSession工厂
        SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Connection connection = sqlSession.getConnection();
        try {
            // 设置手动提交
            connection.setAutoCommit(false);
            ThreadServiceMapper employeeMapper = sqlSession.getMapper(ThreadServiceMapper.class);
            employeeMapper.deleteThread();
            //先做删除操作
            ExecutorService service = ExecutorConfig.getThreadPool();
            List<Callable<Integer>> callableList = new ArrayList<>();
            List<List<ThreadServiceDto>> lists = averageAssign(list, 7);
            for (int i = 0; i < lists.size(); i++) {
                List<ThreadServiceDto> lis = lists.get(i);
                Callable<Integer> callable = () -> employeeMapper.insertThread(lis);
                callableList.add(callable);
            }
            //执行子线程
            List<Future<Integer>> futures = service.invokeAll(callableList);
            for (Future<Integer> future : futures) {
                Integer integer = future.get();
                if (future.get() < 2) {
                    connection.rollback();
                    isRunning = false;
                    return;
                }
            }
            if (isRunning) {
                connection.commit();
            }
            System.out.println("添加完毕");
        } catch (Exception e) {
            //connection.rollback();
            // log.info("error", e);
            System.out.println("002 出现异常" + e);

            // throw new ServiceException(ExceptionCodeEnum.EMPLOYEE_SAVE_OR_UPDATE_ERROR);
        }
    }

    @Transactional
    @Override
    public void bootSynchronousService(List<ThreadServiceDto> list) {

        Runnable task = () -> {
            new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {
                boolean shouldRollback = true;

                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                    threadServiceMapper.insertThread(list);

                    if (shouldRollback) {
                        status.setRollbackOnly();
                    }
                }
            });
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
    }



}
